﻿  
  --get the addon namespace
  local addon, ns = ...
  
  --get the config values
  local LabelUI = ns.LabelUI
  local cfg = ns.cfg

  local toc = LabelUI.toc
  local nomoreplay = LabelUI.noshow
  local Kill = LabelUI.Kill
  local textureBackground
  local texturehilite
  local textureBackground2
  local classcolor
  local dominos
  local bartender4


  local backdrop = {}
  local stancenum = 1
  
  local LoadConfig = function()
	backdrop = cfg.backdrop 
	textureBackground = cfg.textureBackground
	texturehilite = cfg.texturehilite
	textureBackground2 = cfg.textureBackground2
	classcolor = cfg.classcolor 
	dominos = IsAddOnLoaded("Dominos")
	bartender4 = IsAddOnLoaded("Bartender4")	
  end
  
  local function applyBackground(bu)
    --shadows+background
    if cfg.background.showbg or cfg.background.showshadow then
      bu.bg = CreateFrame("Frame", nil, bu)
      bu.bg:SetAllPoints(bu)
      bu.bg:SetPoint("TOPLEFT", bu, "TOPLEFT", -2, 2)
      bu.bg:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", 2, -2)
      bu.bg:SetFrameLevel(bu:GetFrameLevel()-1)
      
      if cfg.background.classcolored then
        cfg.background.backgroundcolor = classcolor
        cfg.background.shadowcolor = classcolor
      end
      
      if cfg.background.showbg and not cfg.background.useflatbackground then 
        local t = bu.bg:CreateTexture(nil,"BACKGROUND",-8)
        t:SetTexture(cfg.textures.buttonback)
        t:SetAllPoints(bu)
        t:SetVertexColor(cfg.background.backgroundcolor.r,cfg.background.backgroundcolor.g,cfg.background.backgroundcolor.b,cfg.background.backgroundcolor.a)
      end  
      
      bu.bg:SetBackdrop(backdrop)
      if cfg.background.useflatbackground then
        bu.bg:SetBackdropColor(cfg.background.backgroundcolor.r,cfg.background.backgroundcolor.g,cfg.background.backgroundcolor.b,cfg.background.backgroundcolor.a)
      end
      if cfg.background.showshadow then
        bu.bg:SetBackdropBorderColor(cfg.background.shadowcolor.r,cfg.background.shadowcolor.g,cfg.background.shadowcolor.b,cfg.background.shadowcolor.a)
      end
    end
  end

  local function ntSetVertexColorFunc(nt, r, g, b, a)
    --do stuff
    local bu = nt:GetParent()
    --print(self:GetName()..": r"..r.."g"..g.."b"..b)--debug
    local action = bu.action
    if r == 0.9 and g==0 and b==0 and action and not IsActionInRange(action) then
	  nt:SetVertexColor(0.9, 0.0, 0.0)
    elseif r==1 and g==1 and b==1 and action and (IsEquippedAction(action)) then
      nt:SetVertexColor(cfg.color.equipped.r,cfg.color.equipped.g,cfg.color.equipped.b,1)
    elseif r==0.5 and g==0.5 and b==1 then
        --blizzard oom color
      nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
    elseif r==1 and g==1 and b==1 then
      nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
    end        
  end
  
  --initial style func

  local function rActionButtonStyler_AB_update(self, elapsed)
	--ActionButton_OnUpdate(self, elapsed)
	local name = self:GetName()
    	local icon = _G[name.."Icon"]
    	local normalTexture = _G[name.."NormalTexture"]
		local isUsable, notEnoughMana
		if self.action then
    		isUsable, notEnoughMana = IsUsableAction(self.action)
		else
			isUsable = true
		end
	local inRange = IsActionInRange(self.action)
	--DEFAULT_CHAT_FRAME:AddMessage(tostring(inRange))
	if ( inRange == 0 ) then
        	icon:SetVertexColor(0.9, 0.0, 0.0);
        	normalTexture:SetVertexColor(0.9, 0.0, 0.0);
    	elseif ( isUsable ) then
        	icon:SetVertexColor(1.0, 1.0, 1.0);
		if normalTexture then normalTexture:SetVertexColor(1.0, 1.0, 1.0) end
    	elseif ( notEnoughMana ) then
        	icon:SetVertexColor(0.5, 0.5, 1.0);
        	normalTexture:SetVertexColor(0.5, 0.5, 1.0);
    	else
        	icon:SetVertexColor(0.4, 0.4, 0.4);
        	if normalTexture then normalTexture:SetVertexColor(1.0, 1.0, 1.0) end
    	end	 
  end
  
  local function styleExtraActionButton(bu, barconf)
    if not bu or (bu and bu.rabs_styled) then return end
    local name = bu:GetName()
    --remove the background texture
	local co  = _G[name.."Count"]
    local bo  = _G[name.."NormalTexture"]
    local ho  = _G[name.."HotKey"]
    local cd  = _G[name.."Cooldown"]
			--local kids = { bu:GetChildren() }
			--for _, bg in ipairs(kids) do
			--	print(bg:GetName())
			--end
    Kill(bo)
    bu.style:SetTexture(nil)
	bo:SetTexture(nil)
    local disableTexture = function(self, texture)
      if texture then
        self:SetTexture(nil)
      end
    end
    hooksecurefunc(bu.style, "SetTexture", disableTexture)
	if cfg.hotkeys.show then
        ho:SetFont(cfg.font, cfg.hotkeys.fontsize, "OUTLINE")
        ho:ClearAllPoints()
        ho:SetPoint(cfg.hotkeys.pos1.a1,bu,cfg.hotkeys.pos1.x,cfg.hotkeys.pos1.y)
        ho:SetPoint(cfg.hotkeys.pos2.a1,bu,cfg.hotkeys.pos2.x,cfg.hotkeys.pos2.y)
    else
        Kill(ho)
    end
	if cfg.itemcount.show then
        co:SetFont(cfg.font, cfg.itemcount.fontsize, "OUTLINE")
        co:ClearAllPoints()
        co:SetPoint(cfg.itemcount.pos1.a1,bu,cfg.itemcount.pos1.x,cfg.itemcount.pos1.y)        
    else
        Kill(co)
    end
	cd:SetPoint("TOPLEFT", bu, "TOPLEFT", cfg.cooldown.spacing, -cfg.cooldown.spacing)
    cd:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -cfg.cooldown.spacing, cfg.cooldown.spacing)
    --remove default texture border
	bu:SetHighlightTexture(cfg.textures.hover)
    bu:SetPushedTexture(cfg.textures.pushed)
    bu:SetCheckedTexture(cfg.textures.checked)
    --bu:SetNormalTexture(cfg.textures.normal)
    bu.icon:SetTexCoord(0.1,0.9,0.1,0.9)
    bu.icon:SetPoint("TOPLEFT", bu, "TOPLEFT", 2.5/barconf.barscale, -2.5/barconf.barscale)
    bu.icon:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -2.5/barconf.barscale, 2.5/barconf.barscale)
    --add a border texture (like normaltexture)
    local layer, sublayer = bu.icon:GetDrawLayer()
    local border = bu:CreateTexture(nil,layer,sublayer+1)
    border:SetTexture(cfg.textures.normal)
    border:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
    border:SetAllPoints(bu)
    bu.border = border
    --apply background
    applyBackground(bu)
	bu.rabs_styled = true
  end


  --local function rActionButtonStyler_AB_style(self)
  local function styleActionButton(bu)
  	  if not bu or (bu and bu.rabs_styled) then
        return
      end
	  local bid = bu:GetParent():GetParent():GetID() or 1
	  if bid == 0 then bid = 1 end
	  local barconf = cfg.bars["bar"..bid]
      if bid == 11 then
	  	barconf = cfg.bars.flyout
	  end
	  
      local action = bu.action
      local name = bu:GetName()
      local bu  = _G[name]
      local ic  = _G[name.."Icon"]
      local co  = _G[name.."Count"]
      local bo  = _G[name.."Border"]
      local ho  = _G[name.."HotKey"]
      local cd  = _G[name.."Cooldown"]
      local na  = _G[name.."Name"]
      local fl  = _G[name.."Flash"]
      local nt  = _G[name.."NormalTexture"]
      local fbg  = _G[name.."FloatingBG"]
	  local fob = _G[name.."FlyoutBorder"]
      local fobs = _G[name.."FlyoutBorderShadow"]
     
      if fbg then Kill(fbg) end
	  if fob then fob:SetTexture(nil) end
      if fobs then fobs:SetTexture(nil) end
      if bo then bo:SetTexture(nil) end
      
      if cfg.hotkeys.show then
        ho:SetFont(cfg.font, cfg.hotkeys.fontsize, "OUTLINE")
        ho:ClearAllPoints()
        ho:SetPoint(cfg.hotkeys.pos1.a1,bu,cfg.hotkeys.pos1.x,cfg.hotkeys.pos1.y)
        ho:SetPoint(cfg.hotkeys.pos2.a1,bu,cfg.hotkeys.pos2.x,cfg.hotkeys.pos2.y)
      elseif not dominos and not bartender4 then
        Kill(ho)
      end
      
      if na then
      	if cfg.macroname.show then
        	na:SetFont(cfg.font, cfg.macroname.fontsize, "OUTLINE")
        	na:ClearAllPoints()
        	na:SetPoint(cfg.macroname.pos1.a1,bu,cfg.macroname.pos1.x,cfg.macroname.pos1.y)
        	na:SetPoint(cfg.macroname.pos2.a1,bu,cfg.macroname.pos2.x,cfg.macroname.pos2.y)
      	elseif not dominos and not bartender4 then
        	Kill(na)
      	end
      end

      if cfg.itemcount.show then
        co:SetFont(cfg.font, cfg.itemcount.fontsize, "OUTLINE")
        co:ClearAllPoints()
        co:SetPoint(cfg.itemcount.pos1.a1,bu,cfg.itemcount.pos1.x,cfg.itemcount.pos1.y)        
      elseif not dominos and not bartender4 then
        Kill(co)
      end
    
      --applying the textures
      fl:SetTexture(cfg.textures.flash)
      bu:SetHighlightTexture(cfg.textures.hover)
      bu:SetPushedTexture(cfg.textures.pushed)
      bu:SetCheckedTexture(cfg.textures.checked)
      bu:SetNormalTexture(cfg.textures.normal)
      if not nt then
        --fix the non existent texture problem (no clue what is causing this)
        nt = bu:GetNormalTexture()
   	  end

      --cut the default border of the icons and make them shiny
      ic:SetTexCoord(0.1,0.9,0.1,0.9)
      ic:SetPoint("TOPLEFT", bu, "TOPLEFT", 2.5/barconf.barscale, -2.5/barconf.barscale)
      ic:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -2.5/barconf.barscale, 2.5/barconf.barscale)
  
      --adjust the cooldown frame
      cd:SetPoint("TOPLEFT", bu, "TOPLEFT", cfg.cooldown.spacing, -cfg.cooldown.spacing)
      cd:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -cfg.cooldown.spacing, cfg.cooldown.spacing)
    
      --apply the normaltexture
      if action and  IsEquippedAction(action) then
        bu:SetNormalTexture(cfg.textures.equipped)
        nt:SetVertexColor(cfg.color.equipped.r,cfg.color.equipped.g,cfg.color.equipped.b,1)
      else
        bu:SetNormalTexture(cfg.textures.normal)
        nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
      end  
      
      --make the normaltexture match the buttonsize
      nt:SetAllPoints(bu)
      
      --disable resetting of textures
      --fl.SetTexture = nomoreplay
      --bu.SetHighlightTexture = nomoreplay
      --bu.SetPushedTexture = nomoreplay
      --bu.SetCheckedTexture = nomoreplay
      --bu.SetNormalTexture = nomoreplay
      
      --hook to prevent Blizzard from reseting our colors
      if nt then hooksecurefunc(nt, "SetVertexColor", ntSetVertexColorFunc) end
      
      --shadows+background
      if not bu.bg then applyBackground(bu) end
      
      bu.rabs_styled = true

	  if bartender4 then --fix the normaltexture
      	nt:SetTexCoord(0,1,0,1)
      	nt.SetTexCoord = function() return end
      	bu.SetNormalTexture = function() return end
      end         
  end
  
  local function styleLeaveButton(bu)
    if not bu or (bu and bu.rabs_styled) then return end
    --shadows+background
    if not bu.bg then applyBackground(bu) end
    bu.rabs_styled = true
  end
  
  --style pet buttons
  local function stylePetButton(bu)
    if not bu or (bu and bu.rabs_styled) then return end
    local name = bu:GetName()
    local bu  = _G[name]
    local ic  = _G[name.."Icon"]
    local fl  = _G[name.."Flash"]
    local nt  = _G[name.."NormalTexture2"]
  
    nt:SetAllPoints(bu)
      
    --applying color
    nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
      
    --setting the textures
    fl:SetTexture(cfg.textures.flash)
    bu:SetHighlightTexture(cfg.textures.hover)
    bu:SetPushedTexture(cfg.textures.pushed)
    bu:SetCheckedTexture(cfg.textures.checked)
    bu:SetNormalTexture(cfg.textures.normal)
    hooksecurefunc(bu, "SetNormalTexture", function(self, texture)
      --make sure the normaltexture stays the way we want it
      if texture and texture ~= cfg.textures.normal then
        self:SetNormalTexture(cfg.textures.normal)
      end
    end)

    --cut the default border of the icons and make them shiny
    ic:SetTexCoord(0.1,0.9,0.1,0.9)
    ic:SetPoint("TOPLEFT", bu, "TOPLEFT", 2, -2)
    ic:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -2, 2)
      
    --shadows+background
    if not bu.bg then applyBackground(bu) end
      
    bu.rabs_styled = true  
  end
 
  
  --style shapeshift buttons
  local function styleStanceButton(bu)  
  	if not bu or (bu and bu.rabs_styled) then return end
    local name = bu:GetName()
    local bu  = _G[name]
    local ic  = _G[name.."Icon"]
    local fl  = _G[name.."Flash"]
    local nt  = _G[name.."NormalTexture2"]
    nt:SetAllPoints(bu)
      
    --applying color
    nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
    --setting the textures
    fl:SetTexture(cfg.textures.flash)
    bu:SetHighlightTexture(cfg.textures.hover)
    bu:SetPushedTexture(cfg.textures.pushed)
    bu:SetCheckedTexture(cfg.textures.checked)
    bu:SetNormalTexture(cfg.textures.normal)
    
     --cut the default border of the icons and make them shiny
    ic:SetTexCoord(0.1,0.9,0.1,0.9)
    ic:SetPoint("TOPLEFT", bu, "TOPLEFT", 2.5/cfg.bars.stancebar.barscale, -2.5/cfg.bars.stancebar.barscale)
    ic:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -2.5/cfg.bars.stancebar.barscale, 2.5/cfg.bars.stancebar.barscale)
      
    --shadows+background
    if not bu.bg then applyBackground(bu) end
    bu.rabs_styled = true  
    --
	--if (num ~= stancenum and num > 0 and toc > 50000) then
	--	StanceBarFrame:GetParent():SetWidth(cfg.bars.stancebar.buttonsize*num+cfg.bars.stancebar.buttonspacing*(num-1))
	--	stancenum = num
	--end  
  end

  local function styleBag(bu)
      if not bu or (bu and bu.rabs_styled) then return end
      local name = bu:GetName()
      local bu  = _G[name]
      local ic  = _G[name.."IconTexture"]
      --local fl  = _G[name.."Flash"]
      local nt  = _G[name.."NormalTexture"]
  
      nt:SetAllPoints(bu)
      
      --applying color
      nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
      
      --setting the textures
      --fl:SetTexture(cfg.textures.flash)
      bu:SetHighlightTexture(cfg.textures.hover)
      bu:SetPushedTexture(cfg.textures.pushed)
      bu:SetCheckedTexture(cfg.textures.checked)
      bu:SetNormalTexture(cfg.textures.normal)
    
      --cut the default border of the icons and make them shiny
      ic:SetTexCoord(0.1,0.9,0.1,0.9)
      ic:SetPoint("TOPLEFT", bu, "TOPLEFT", 2, -2)
      ic:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -2, 2)
      
      --shadows+background
      if not bu.bg then applyBackground(bu) end      
  end
 
  local function stylePossessButton(bu)
    if not bu or (bu and bu.rabs_styled) then return end
    local name = bu:GetName()
    local ic  = _G[name.."Icon"]
    local fl  = _G[name.."Flash"]
    local nt  = _G[name.."NormalTexture"]
    nt:SetAllPoints(bu)
    --applying color
    nt:SetVertexColor(cfg.color.normal.r,cfg.color.normal.g,cfg.color.normal.b,1)
    --setting the textures
    fl:SetTexture(cfg.textures.flash)
    bu:SetHighlightTexture(cfg.textures.hover)
    bu:SetPushedTexture(cfg.textures.pushed)
    bu:SetCheckedTexture(cfg.textures.checked)
    bu:SetNormalTexture(cfg.textures.normal)
    --cut the default border of the icons and make them shiny
    ic:SetTexCoord(0.1,0.9,0.1,0.9)
    ic:SetPoint("TOPLEFT", bu, "TOPLEFT", 2, -2)
    ic:SetPoint("BOTTOMRIGHT", bu, "BOTTOMRIGHT", -2, 2)
    --shadows+background
    if not bu.bg then applyBackground(bu) end
    bu.rabs_styled = true
  end
 
  function rActionButtonStyler_HideGrid (button) 
    if not InCombatLockdown() then 
    local showgrid = button:GetAttribute("showgrid");
     
    if ( showgrid > 1 ) then
        button:SetAttribute("showgrid", 0);
    elseif ( showgrid > 0 ) then
        button:SetAttribute("showgrid", showgrid - 1);
    end
     
    if ( button:GetAttribute("showgrid") == 0 and not HasAction(button.action) ) then
        button:Hide();
    end
    end
  end

  local function updateHotkey(self, actionButtonType)
    local ho = _G[self:GetName().."HotKey"]
    if ho and not cfg.hotkeys.show and ho:IsShown() then
      ho:Hide()
    end
  end
  
  ---------------------------------------
  -- CALLS // HOOKS
  ---------------------------------------
  local function Init()
  
  	LoadConfig()
	
	for i = 1, NUM_ACTIONBAR_BUTTONS do
      styleActionButton(_G["ActionButton"..i])
      styleActionButton(_G["MultiBarBottomLeftButton"..i])
      styleActionButton(_G["MultiBarBottomRightButton"..i])
      styleActionButton(_G["MultiBarRightButton"..i])
      styleActionButton(_G["MultiBarLeftButton"..i])
    end
    for i = 1, 6 do
      styleActionButton(_G["OverrideActionBarButton"..i])
    end
    --style leave button
    styleLeaveButton(OverrideActionBarLeaveFrameLeaveButton)
    styleLeaveButton(rABS_LeaveVehicleButton)
    --petbar buttons
    for i=1, NUM_PET_ACTION_SLOTS do
      stylePetButton(_G["PetActionButton"..i])
    end
    --stancebar buttons
    for i=1, NUM_STANCE_SLOTS do
      styleStanceButton(_G["StanceButton"..i])
    end
    --possess buttons
    for i=1, NUM_POSSESS_SLOTS do
      stylePossessButton(_G["PossessButton"..i])
    end
    --extraactionbutton1
    styleExtraActionButton(ExtraActionButton1, cfg.bars.extrabar)
	--bag
	styleBag(MainMenuBarBackpackButton)
    --spell flyout
    SpellFlyoutBackgroundEnd:SetTexture(nil)
    SpellFlyoutHorizontalBackground:SetTexture(nil)
    SpellFlyoutVerticalBackground:SetTexture(nil)
    local function checkForFlyoutButtons(self)
      local NUM_FLYOUT_BUTTONS = 10
      for i = 1, NUM_FLYOUT_BUTTONS do
        styleActionButton(_G["SpellFlyoutButton"..i])
      end
    end
    SpellFlyout:HookScript("OnShow",checkForFlyoutButtons)

    --dominos styling
    if dominos then
      --print("Dominos found")
      for i = 1, 60 do
        styleActionButton(_G["DominosActionButton"..i])
      end
    end
    --bartender4 styling
    if bartender4 then
      --print("Bartender4 found")
      for i = 1, 120 do
        styleActionButton(_G["BT4Button"..i])
      end
    end

    --hide the hotkeys if needed
    if not dominos and not bartender4 and not cfg.hotkeys.show then
      hooksecurefunc("ActionButton_UpdateHotkeys",  updateHotkey)
    end

  end
  LabelUI:AddInit(Init, "StyleActionBars")